#include "../include/System.h"

#define START 1
#define END 2
///home/zcf/公共的/keshe
System::System()
:width(1280),height(720),employee_number(0)
{}


void System::start()
{
    namedWindow("print",WINDOW_AUTOSIZE);
    loading(START);
    system("clear");
    waitKey(50);
    while(1)  
    {
        int selection = showMenu();
        switch ((selection))
        {
        case 1 :
            addEmployee();
            break;
        case 2 :
            search();
            break;
        case 3:
            modify();
            break;
        case 4:
            removal();
            break;
        case 5:
            save();
            break;
        case 6:
            load();
            break;
        case 7:
            recover();
            break;
        case 8:
            count();
            break;
        }
    }


}

void System::loading(int code)
{
    if(code == START)
    {
        cv::Mat loading_img = cv::imread("/home/zcf/公共的/keshe/images/loading.png");
        if(loading_img.empty())
        {
            cout<<"erro img"<<endl;
            waitKey(0);
        }
        cv::Mat background = cv::Mat::zeros(loading_img.size(),CV_8UC3);
        cv::Mat inv;
        cv::cvtColor(loading_img,inv,COLOR_BGR2GRAY);

        cv::threshold(inv,inv,50,255,THRESH_BINARY_INV);

        vector<vector<cv::Point>> contours;
        cv::findContours(inv,contours,RETR_LIST,CHAIN_APPROX_NONE);

        for(int i = 0;i<contours.size();++i)
        {
            cv::RNG rng(1+i);
            cv::Scalar color = Scalar(255,255,255);
            cv::drawContours(background,contours,i,color,3);
            /*for(int j = 0;j<contours[j].size();++j)
            {
                circle(background,contours[i][j],1,color);
                
            }*/
            imshow("print",background);
            cv::waitKey(100);
        }
    }
    else{

    }
}
int System::showMenu()
{
    cv::Mat menu = cv::imread("/home/zcf/公共的/keshe/images/menu.png");
    if(menu.empty())
    {
        cout<<"erro img"<<endl;
    }
    //resize(menu,menu,Size(width,height));
    cv::imshow("print",menu);
    waitKey(20);

    int selection = 0;
    do
    {
        cout<<"Please input your choose "<<endl;
        cin>>selection;
        
        system("clear");
    }
    while(selection <= 0 || selection > 8);

    return selection;
}


void System::addEmployee()
{
    cv::Mat add = cv::imread("/home/zcf/公共的/keshe/images/add.png");
    cv::Mat waiting = cv::imread("/home/zcf/公共的/keshe/images/waiting.png");
    if(add.empty()|waiting.empty())
        return;

    imshow("print",add);
    waitKey(20);
    int selection = 0;
     do
    {
        cout<<"Please input your choose"<<endl;
        cin>>selection;
        
        system("clear");
    }
    while(selection <= 0 && selection > 4);

    imshow("print",waiting);
    waitKey(20);
    switch (selection)
    {
    case 1:
        {
            shared_ptr<Manager> manager = make_shared<Manager>();
            manager->create();
            employees.push_back(manager);
        }
            break;
    case 2:
        {
            shared_ptr<Engineer> engineer = make_shared<Engineer>();
            engineer->create();
            employees.push_back(engineer);
        }
            break;
    case 3:
        {
            shared_ptr<Salesman> salesman = make_shared<Salesman>();
            salesman->create();
            employees.push_back(salesman);
        }
            break;
    case 4:
        {
            shared_ptr<Desginer> desginer = make_shared<Desginer>();
            desginer->create();
            employees.push_back(desginer);
        }
            break;
    
    };
    system("clear");

}



void System::search()
{
    cv::Mat cancanneed = imread("/home/zcf/公共的/keshe/images/cancanneed.png");
    if(cancanneed.empty())
    {
        cv::waitKey(0);
    }
    cv::imshow("print",cancanneed);
    cv::waitKey(20);
    system("clear");
    cout<<"Please input the name you are searhcing"<<endl;
    string name_;
    cin>>name_;
    cout<<"input: "<<name_<<endl;
    int index = -1;
    for(int i = 0;i<employees.size();++i)
    {
        cout<<"enum"<<employees[i]->getName()<<endl;
        if(employees[i]->getName() == name_)
        {
            index = i;
            break;
        }
    }
    if(index != -1)
    {
        system("clear");
        cout<<"you have found! the info of this worker have been printed"<<endl;
        employees[index]->print();
        cv::waitKey(20);
    }
    else
    {
        system("clear");
        cout<<"404 NOT FOUND!"<<endl;
    }
    this->pause();
    system("clear");
}



void System::modify()
{
    cv::Mat background = imread("/home/zcf/公共的/keshe/images/modify.png");
    cv::imshow("print",background);
    cv::waitKey(20);
    string name_;
    cout<<"please input the name you want to modify"<<endl;
    cin>>name_;

    int index = -1;
    for(int i = 0;i<employees.size();++i)
    {
        if(employees[i]->getName() == name_)
        {
            index = i;
            break;
        }
    }
    system("clear");
    if(index != -1)
    {
       cout<<"you have found! now lets do it"<<endl;
       switch(employees[index]->getJob())
       {
           case manager :
           {
               employees[index].reset();
               employees.erase(employees.begin()+index);
               shared_ptr<Manager> tmp = make_shared<Manager>();
               tmp->create();
               employees.push_back(tmp);
               break;
           }
           case engineer:
           {
                employees[index].reset();
               employees.erase(employees.begin()+index);
               shared_ptr<Engineer> tmp = make_shared<Engineer>();
               tmp->create();
               employees.push_back(tmp);
               break;
           }
           case salesman:
           {
               employees[index].reset();
               employees.erase(employees.begin()+index);
               shared_ptr<Salesman> tmp = make_shared<Salesman>();
               tmp->create();
               employees.push_back(tmp);
               break;
           }
           case desginer:
           {
               employees[index].reset();
               employees.erase(employees.begin()+index);
               shared_ptr<Desginer> tmp = make_shared<Desginer>();
               tmp->create();
               employees.push_back(tmp);
               break;
           }
       }
    }
    else
    {
        system("clear");
        cout<<"404 NOT FOUND!"<<endl;
    }

}

void System::removal()
{
    cv::Mat background = imread("/home/zcf/公共的/keshe/images/removal.png");
    cv::imshow("print",background);
    cv::waitKey(20);
    string name_;
    cout<<"please input the name you want to removal"<<endl;
    cin>>name_;

    int index = -1;
    for(int i = 0;i<employees.size();++i)
    {
        if(employees[i]->getName() == name_)
        {
            index = i;
            break;
        }
    }
    system("clear");
    if(index != -1)
    {
       cout<<"you have found! now lets do it"<<endl;
       switch(employees[index]->getJob())
       {
           case manager :
           {
                recycle_bin.push_back(employees[index]);    
                employees.erase(employees.begin()+index);
                break;
           }
           case engineer:
           {
               recycle_bin.push_back(employees[index]);
                employees.erase(employees.begin()+index);
                break;
           }
           case salesman:
           {
               recycle_bin.push_back(employees[index]);
               employees.erase(employees.begin()+index);
               break;
           }
           case desginer:
           {
               recycle_bin.push_back(employees[index]);
               employees.erase(employees.begin()+index);
               break;
           }
       }
    }
    else
    {
        system("clear");
        cout<<"404 NOT FOUND!"<<endl;
    }
    pause();
    system("clear");

}

void write(FileStorage& fs,const string& ,const Employee& x)
{
    x.write(fs);
}
void read(const FileNode& node, Employee& x, const Employee& default_value = Manager()){
    if(node.empty())
        return;
    else
        x.read(node);
}

void System::save()
{
    cv::FileStorage fs;
    fs.open("/home/zcf/公共的/keshe/backup/backup.yaml",FileStorage::WRITE);
    if(!fs.isOpened())
    {
        cout<<"open error"<<endl;
    }
    int total_number = employees.size();
    int m=0,e=0,s=0,d=0;
    for(int i = 0;i < employees.size();++i)
    {
       switch (employees[i]->getJob())
       {
        case manager:
        {
            fs<<"Manager"+to_string(m)<<*employees[i];
            m++;
               
        }
           break;
        case engineer:
        {
            fs<<"Engineer"+to_string(e)<<*employees[i];
            e++;
        }
            break;
        case salesman:
        {
            fs<<"Salesman"+to_string(s)<<*employees[i];
            s++;
        }
            break;
        case desginer:
        {
            fs<<"Desginer"+to_string(d)<<*employees[i];
            d++;
        }
            break;
       }
    }
    fs<<"total_number "<<total_number;
    fs<<"manager_cnt"<<m;
    fs<<"engineer_cnt"<<e;
    fs<<"salesman_cnt"<<s;
    fs<<"desginer_cnt"<<d;
    cout<<"save successfully!"<<endl;
    pause();
    system("clear");
}

void System::load()
{
    cv::FileStorage fs;
    fs.open("/home/zcf/公共的/keshe/backup/backup.yaml",FileStorage::READ);
    if(!fs.isOpened())
    {
        cout<<"open error"<<endl;
    }

    int manager_cnt = (int)fs["manager_cnt"];
    for(int i = 0;i<manager_cnt;++i)
    {
        shared_ptr<Manager> manager = make_shared<Manager>(); 
        fs["Manager"+to_string(i)] >> *manager;
        employees.push_back(manager);
    }

    int engineer_cnt = (int)fs["engineer_cnt"];
    for(int i = 0;i<engineer_cnt;++i)
    {
        shared_ptr<Engineer> engineer = make_shared<Engineer>();
        fs["Engineer"+to_string(i)]>>*engineer;
        employees.push_back(engineer);
    }

    int desginer_cnt = (int)fs["desginer_cnt"];
    for(int i = 0;i<desginer_cnt;++i)
    {
        shared_ptr<Desginer> desginer = make_shared<Desginer>();
        fs["Dsginer"+to_string(i)]>>*desginer;
        employees.push_back(desginer);
    }

    int salesman_cnt = (int)fs["salesman_cnt"];
    for(int i = 0;i<salesman_cnt;++i)
    {
        shared_ptr<Salesman> salesman = make_shared<Salesman>();
        fs["Salesman"+to_string(i)]>>*salesman;
        employees.push_back(salesman);
    }
    cout<<"load successfully!"<<endl;
    pause();
    system("clear");
}

void System::recover()
{
    int max_size = recycle_bin.size()>5 ? 5 : recycle_bin.size();
    for(int i =  0;i<recycle_bin.size();++i)
    {
        cout<<"recycle bin:"<<endl;
        cout<<"name: "<<recycle_bin[i]->getName()<<endl;;   
    }
    if(max_size > 5)
        cout<<"to many to list..."<<endl;

    cout<<endl<<"Please input the name you want to recover"<<endl;
    string name_;
    cin>>name_;

    int index = -1;
    for(int i = 0;i<employees.size();++i)
    {
        if(recycle_bin[i]->getName() == name_)
        {
            index = i;
            break;
        }
    }
    if(index != -1)
    {
        employees.push_back(recycle_bin[index]);
        recycle_bin[index].reset();
        recycle_bin.erase(recycle_bin.begin()+index);
        system("clear");
        cout<<"recover successfully"<<endl;
    }
    else{
        system("clear");
        cout<<"NOT FOUND!"<<endl;
    }
    pause();
    system("clear");
}


void System::count()
{
    int sum = 0;
    vector<string> low;
    vector<string> mid;
    vector<string> high;
    for(int i = 0;i<employees.size();i++)
    {
        int total = 0,avg = 0;
        employees[i]->countSalary(total,avg);
        sum += total;   
        if(total > 3000)
        {
            high.push_back(employees[i]->getName());
        }
        else if(total > 2000)
        {
            mid.push_back(employees[i]->getName());
        }
        else
        {
            low.push_back(employees[i]->getName());
        }
    }
    
    int average = sum/employees.size();
    
    for(int i = 0;i<employees.size();i++)
    {
        cout<<*employees[i]<<endl;
    }


    cout<<"------------------------------------------------------"<<endl;
    cout<<"average salary: "<<average<<endl;
    cout<<">3000:"<<high.size()<<endl;//<<"      pecentage:"<<float(high.size()/employees.size())*100<<"%"<<endl;
    cout<<"(2000,3000):"<<mid.size()<<endl;//"     pecentage:"<<float(mid.size()/employees.size())*100<<"%"<<endl;
    cout<<"<2000:"<<low.size()<<endl;//"      pecentage:"<<float(low.size()/employees.size())*100<<"%"<<endl;
    cout<<endl<<endl;
    pause();
    system("clear");
}





/*void System::save() 
{
    cv::FileStorage fs;
    fs.open("/home/zcf/公共的/keshe/backup/backup.yaml",FileStorage::WRITE);
    if(!fs.isOpened())
    {
        cout<<"open error"<<endl;
    }
    int total_number = employees.size();
    fs<<"total_number "<<total_number;
    for(int i = 0;i < employees.size();++i)
    {
        fs<<"job "+to_string(i)<<employees[i]->getJob();
        fs<<"name "+to_string(i)<<employees[i]->name;
        fs<<"age "+to_string(i)<<employees[i]->age;
        fs<<"basic_salary "+to_string(i)<<employees[i]->basic_salary;
        fs<<"id "+to_string(i)<<employees[i]->id;
        fs<<"job_salary "+to_string(i)<<employees[i]->job_salary;
        fs<<"subsidy "+to_string(i)<<employees[i]->subsidy;
        fs<<"insurance "+to_string(i)<<employees[i]->insurance;
        fs<<"face "+to_string(i)<<employees[i]->face;
    }
    
    fs.release();
    system("clear");
    cout<<"save file successfully!"<<endl;
    pause();
}

void System::load()
{
    cv::FileStorage fs;
    fs.open("/home/zcf/公共的/keshe/backup/backup.yaml",FileStorage::READ);
    if(!fs.isOpened())
    {
        cout<<"open error"<<endl;
    }
}*/